#!/usr/bin/env node

// 电调校准脚本
const { exec } = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(exec);

console.log("🔧 电调校准脚本");
console.log("⚠️  警告: 校准过程中电调会发出蜂鸣声，请确保螺旋桨已移除!");

async function calibrateESC() {
  try {
    // 初始化引脚
    await execAsync('gpio -g mode 13 out');
    console.log("✅ 引脚13初始化为输出模式");
    
    // 步骤1: 发送最大油门信号 (2.0ms)
    console.log("\n步骤1: 发送最大油门信号 (2.0ms)...");
    console.log("请听电调的蜂鸣声，通常会发出确认音调");
    await sendPWMSignal(13, 2.0, 3000); // 保持3秒
    
    // 步骤2: 发送最小油门信号 (1.0ms)
    console.log("\n步骤2: 发送最小油门信号 (1.0ms)...");
    console.log("请听电调的蜂鸣声，通常会发出不同的确认音调");
    await sendPWMSignal(13, 1.0, 3000); // 保持3秒
    
    // 步骤3: 发送中性信号 (1.5ms)
    console.log("\n步骤3: 发送中性信号 (1.5ms)...");
    await sendPWMSignal(13, 1.5, 1000); // 保持1秒
    
    console.log("\n✅ 电调校准完成!");
    console.log("现在可以测试控制了");
    
  } catch (error) {
    console.error("❌ 电调校准失败:", error.message);
  }
}

// 发送PWM信号的辅助函数
async function sendPWMSignal(pin, dutyCycleMs, durationMs) {
  const periodMs = 20; // 50Hz = 20ms周期
  const highTimeMs = dutyCycleMs;
  const lowTimeMs = periodMs - dutyCycleMs;
  
  const cycles = Math.floor(durationMs / periodMs);
  
  for (let i = 0; i < cycles; i++) {
    await execAsync(`gpio -g write ${pin} 1`);
    await sleep(highTimeMs);
    await execAsync(`gpio -g write ${pin} 0`);
    await sleep(lowTimeMs);
  }
}

// 精确延时函数（毫秒）
function sleep(ms) {
  return new Promise(resolve => {
    const start = Date.now();
    while (Date.now() - start < ms) {
      // 空循环等待
    }
    resolve();
  });
}

async function main() {
  console.log("🚀 开始电调校准程序");
  console.log("请确保:");
  console.log("  1. 电调已正确连接到GPIO 13");
  console.log("  2. 电机电源已连接");
  console.log("  3. 螺旋桨已移除");
  console.log("  4. 准备听取电调的蜂鸣声反馈");
  
  const readline = require('readline');
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });
  
  rl.question('\n是否开始校准? (y/N): ', async (answer) => {
    if (answer.toLowerCase() === 'y') {
      await calibrateESC();
    } else {
      console.log("_calibration cancelled_");
    }
    rl.close();
  });
}

main();